﻿namespace Nello
{
    using System;
    using System.Data.Common;
    using System.Reflection;
    using System.Runtime.InteropServices;

    public class ClassFactory
    {
        public static Assembly GetAppCodeAssembly()
        {
            Assembly asse = Assembly.GetExecutingAssembly();
            foreach (Assembly asa in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (asa.FullName.StartsWith("App_Code"))
                {
                    return asa;
                }
            }
            return asse;
        }

        public static System.Data.Common.DbProviderFactory GetDbProviderFactory(string providername)
        {
            if (providername == "")
            {
                providername = AppSettings.Get("ClassFactory.ProviderName");
            }
            return DbProviderFactories.GetFactory(providername);
        }

        public static T GetObject<T>(string className)
        {
            return GetObject<T>("", className);
        }

        public static T GetObject<T>(string assemblyName, string className)
        {
            return (T) Activator.CreateInstance(GetTypeByName(assemblyName, className));
        }

        public static Type GetTypeByName(string className)
        {
            return GetTypeByName("", className);
        }

        public static Type GetTypeByName(string assemblyName, string className)
        {
            Assembly ass;
            if (assemblyName == "")
            {
                ass = GetAppCodeAssembly();
            }
            else
            {
                ass = Assembly.Load(assemblyName);
            }
            return ass.GetType(className);
        }

        public static void Invoke(object obj, string methodName)
        {
            obj.GetType().GetMethod(methodName).Invoke(obj, null);
        }

        private static void ParseClassInfo(string classInfo, out string assemblyName, out string className)
        {
            string[] ss = classInfo.Split(new char[] { '!' });
            if (ss.Length == 2)
            {
                assemblyName = ss[0];
                className = ss[1];
            }
            else
            {
                assemblyName = "";
                className = classInfo;
            }
        }

        public static string ConnectionString
        {
            get
            {
                string cnntype = AppSettings.Get("ClassFactory.ConnectionType");
                string[] cnninfo = cnntype.Split(".".ToCharArray());
                if (cnninfo[0] == "AppSettings")
                {
                    return AppSettings.Get(cnntype.Substring(12));
                }
                if (cnninfo[0] == "Class")
                {
                    string classInfo = cnntype.Substring(6);
                    string assemblyName = "";
                    string className = "";
                    ParseClassInfo(classInfo, out assemblyName, out className);
                    return GetObject<IConnectionInfo>(assemblyName, className).ConnectionString;
                }
                return "";
            }
        }

        public static System.Data.Common.DbProviderFactory DbProviderFactory
        {
            get
            {
                return GetDbProviderFactory("");
            }
        }
    }
}

